home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / C / Applications / MacWT 0.9 / wt Mac Source / Blit.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-10-10  |  3.9 KB  |  167 lines  |  [TEXT/CWIE]

  1. /*
  2. ** File:        Blit.c
  3. **
  4. ** Written by:    Bill Hayden
  5. **                Nikol Software
  6. **
  7. ** Copyright © 1995 Nikol Software
  8. ** All rights reserved.
  9. **
  10. ** Based on 'BlitCmp' code from Apple Computer, available on the develop 18 CD.
  11. */
  12.  
  13.  
  14. #include "Blit.h"
  15.  
  16.  
  17. //static long        *SourceAddresses;
  18. //static long        *DestinationAddresses;
  19. static short    height;
  20. static long        srcRowBytes;
  21. static long        dstRowBytes;
  22. static long        srcLeft;
  23.  
  24.  
  25. void InitBlit(PixMapPtr srcPM, PixMapPtr dstPM, Rect *srcRect, Rect *dstRect)
  26. {
  27.     height = srcRect->bottom - srcRect->top;    // No scaling allowed
  28.     
  29.     srcRowBytes = srcPM->rowBytes & 0x3fff;
  30.     dstRowBytes = dstPM->rowBytes & 0x3fff;
  31.     
  32.     // get the bit offset to the src left edge
  33.     srcLeft = (srcRect->left - srcPM->bounds.left) * srcPM->pixelSize;
  34.     
  35.     // eventually, this function will calculate row addresses and other static data beforehand
  36. }
  37.  
  38.  
  39.  
  40. pascal void CopyBlit(PixMapPtr srcPM, PixMapPtr dstPM, Rect *srcRect, Rect *dstRect)
  41. {
  42.     long            dstLeft;
  43.     long            dstRight;
  44.     long *            srcRow;
  45.     long *            dstRow;
  46.     register long *    srcPtr;
  47.     register long *    dstPtr;
  48.     long            leftMask;
  49.     long            notLeftMask;
  50.     long            rightMask;
  51.     long            notRightMask;
  52.     long            dstLong;
  53.     short            dstLongs;
  54.     short            localheight = height;
  55.     long            offset;
  56.     long            timesCopy;
  57.  
  58.     srcRow = (long *) srcPM->baseAddr;
  59.     dstRow = (long *) dstPM->baseAddr;
  60.         
  61.     // offset the src ptr to the first long
  62.     srcRow += srcLeft >> 5;
  63.     
  64.     // get the bit offset to the dst left and right edges
  65.     dstLeft = (dstRect->left - dstPM->bounds.left) * dstPM->pixelSize;
  66.     dstRight = (dstRect->right - dstPM->bounds.left) * dstPM->pixelSize;
  67.     
  68.     // get the number of middle longs to do minus the left edge long
  69.     dstLongs = ((dstRight - dstLeft) >> 5) - 1;
  70.     
  71.     // offset the dst Ptr to the first long
  72.     dstRow += dstLeft >> 5;
  73.  
  74.     // now compute left and right masks for the dst
  75.     dstLeft &= 0x1f;
  76.     leftMask = ( 1 << dstLeft ) - 1;
  77.     notLeftMask = ~leftMask;
  78.     
  79.     dstRight &= 0x1f;
  80.     notRightMask = ( 1 << dstRight ) - 1;
  81.     rightMask = ~notRightMask;
  82.     
  83.     // offset the src and dst ptrs to the first row
  84.     offset = (srcRect->top - srcPM->bounds.top) * srcRowBytes;
  85.     srcRow += (long *) offset;
  86.     
  87.     offset = (dstRect->top - dstPM->bounds.top) * dstRowBytes;
  88.     dstRow += (long *) offset;
  89.     
  90.     /* check if we need to do the left and right mask */
  91.     if ( leftMask )
  92.         {
  93.         if ( notLeftMask == 0 )
  94.             {
  95.             leftMask = 0;
  96.             dstLongs++;
  97.             }
  98.         }
  99.         
  100.     if ( rightMask )
  101.         {
  102.         if ( notRightMask == 0 )
  103.             {
  104.             rightMask = 0;
  105.             dstLongs++;
  106.             }
  107.         }
  108.         
  109.     //for ( ; localheight >= 0; --localheight )
  110.     // changing the above 'for()' to the below 'while()' is what made this blit routine
  111.     // faster than CopyBits - a speed improvement equal to all other changes I had made
  112.     // previously.  (about 4 to 5 milliseconds, in case you were wondering)
  113.     // Lesson: the true bottlenecks are not always the obvious ones
  114.     while (localheight--)
  115.         {
  116.         srcPtr = srcRow;
  117.         dstPtr = dstRow;
  118.         
  119.         /* do the masked left edge */
  120.         if ( leftMask )
  121.             {
  122.             dstLong = *srcPtr++ & leftMask;
  123.             dstLong |= *dstPtr & notLeftMask;
  124.             *dstPtr++ = dstLong;
  125.             }
  126.  
  127.         /* do the middle longs with Duff's device */
  128.         timesCopy = (dstLongs + 15) >> 4;
  129.         
  130.         switch( dstLongs & 0xF )
  131.             {
  132.             case 0:    do
  133.                     {    *dstPtr++ = *srcPtr++;
  134.             case 15:    *dstPtr++ = *srcPtr++;
  135.             case 14:    *dstPtr++ = *srcPtr++;
  136.             case 13:    *dstPtr++ = *srcPtr++;
  137.             case 12:    *dstPtr++ = *srcPtr++;
  138.             case 11:    *dstPtr++ = *srcPtr++;
  139.             case 10:    *dstPtr++ = *srcPtr++;
  140.             case 9:        *dstPtr++ = *srcPtr++;
  141.             case 8:        *dstPtr++ = *srcPtr++;
  142.             case 7:        *dstPtr++ = *srcPtr++;
  143.             case 6:        *dstPtr++ = *srcPtr++;
  144.             case 5:        *dstPtr++ = *srcPtr++;
  145.             case 4:        *dstPtr++ = *srcPtr++;
  146.             case 3:        *dstPtr++ = *srcPtr++;
  147.             case 2:        *dstPtr++ = *srcPtr++;
  148.             case 1:        *dstPtr++ = *srcPtr++;
  149.                     } while( --timesCopy > 0 );
  150.             }
  151.  
  152.         /* do the masked right edge */
  153.         if ( rightMask )
  154.             {
  155.             dstLong = *srcPtr & rightMask;
  156.             dstLong |= *dstPtr & notRightMask;
  157.             *dstPtr = dstLong;
  158.             }
  159.         
  160.         /* bump to the next row */
  161.         srcRow += (long *) srcRowBytes;
  162.         dstRow += (long *) dstRowBytes;
  163.         }
  164. }
  165.  
  166.  
  167.